package controller

import (
	"errors"
	"mini-app/config/mysql"
	"mini-app/internal/app/admin/service"
	"mini-app/internal/models"
	"strconv"

	"192.168.1.75/go-pkg/response"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

type OnlineEvent struct{}

func (OnlineEvent) Create(c *gin.Context) {
	var params models.OnlineEvent
	c.ShouldBindBodyWith(&params, binding.JSON)
	id, err := service.OnlineEvent{}.Create(c.Request.Context(), params)
	response.JSON(c, gin.H{
		"id": id,
	}, err)
}

func (OnlineEvent) Update(c *gin.Context) {
	var params models.OnlineEvent
	c.ShouldBindBodyWith(&params, binding.JSON)
	err := service.OnlineEvent{}.Update(c.Request.Context(), params)
	response.JSON(c, nil, err)
}

func (OnlineEvent) Delete(c *gin.Context) {
	var params struct {
		ID string `json:"id"`
	}
	c.ShouldBindBodyWith(&params, binding.JSON)
	err := service.OnlineEvent{}.Delete(c.Request.Context(), params.ID)
	response.JSON(c, nil, err)
}

func (OnlineEvent) Detail(c *gin.Context) {
	detail := service.OnlineEvent{}.Detail(c.Request.Context(), c.Query("id"))
	if detail == nil {
		response.JSON(c, nil, errors.New("活动不存在"))
		return
	}

	response.JSON(c, detail, nil)
}

func (OnlineEvent) List(c *gin.Context) {
	name := c.Query("name")
	status, _ := strconv.Atoi(c.Query("status"))
	page, _ := strconv.Atoi(c.Query("page"))
	limit, _ := strconv.Atoi(c.Query("limit"))
	list, total := service.OnlineEvent{}.List(c.Request.Context(), name, status, page, limit)
	response.JSON(c, gin.H{
		"list":  list,
		"total": total,
	}, nil)
}

// WinnerConfig 中奖配置
func (OnlineEvent) WinnerConfig(c *gin.Context) {
	var params struct {
		OnlineEventID string `json:"online_event_id"`
		UserID        string `json:"user_id"`
		PuppetUserID  string `json:"puppet_user_id"`
	}
	err := c.ShouldBindBodyWith(&params, binding.JSON)
	if err != nil {
		response.JSON(c, nil, errors.Join(errors.New("参数错误"), err))
		return
	}

	err = service.OnlineEvent{}.WinnerConfig(c.Request.Context(), params.OnlineEventID, params.UserID, params.PuppetUserID)
	response.JSON(c, nil, err)
}

// WinnerList 中奖列表
func (OnlineEvent) WinnerList(c *gin.Context) {
	var params struct {
		OnlineEventID string `form:"online_event_id"`
		Page          int    `form:"page"`
		Limit         int    `form:"limit"`
		IsPuppetUser  bool   `form:"is_puppet_user,omitempty"` //默认筛选真实用户
	}

	err := c.ShouldBindWith(&params, binding.Query)
	if err != nil {
		response.JSON(c, nil, errors.Join(errors.New("参数错误"), err))
		return
	}

	list, total, err := service.OnlineEvent{}.WinnerList(c, params.OnlineEventID, params.Page, params.Limit, params.IsPuppetUser)
	if err != nil {
		response.JSON(c, nil, err)
		return
	}

	response.JSON(c, gin.H{
		"list":  list,
		"total": total,
	}, nil)
}

// UserList 参与用户列表
func (OnlineEvent) UserList(c *gin.Context) {
	var params struct {
		OnlineEventID string `form:"online_event_id"`
		Page          int    `form:"page"`
		Limit         int    `form:"limit"`
		IsPuppetUser  *bool  `form:"is_puppet_user,omitempty"`
	}

	err := c.ShouldBindWith(&params, binding.Query)
	if err != nil {
		response.JSON(c, nil, err)
		return
	}

	list, total, err := service.OnlineEvent{}.UserList(c.Request.Context(), params.OnlineEventID, params.Page, params.Limit, params.IsPuppetUser)
	if err != nil {
		response.JSON(c, nil, err)
		return
	}

	response.JSON(c, gin.H{
		"list":  list,
		"total": total,
	}, nil)
}

func (OnlineEvent) SelectedUserList(c *gin.Context) {
	page, _ := strconv.Atoi(c.Query("page"))
	limit, _ := strconv.Atoi(c.Query("limit"))
	list, total, err := service.OnlineEvent{}.SelectedUserList(c.Request.Context(), c.Query("online_event_id"), page, limit)
	if err != nil {
		response.JSON(c, nil, err)
		return
	}

	response.JSON(c, gin.H{
		"list":  list,
		"total": total,
	}, nil)
}

// Draw 开奖
func (OnlineEvent) Draw(c *gin.Context) {
	var params struct {
		OnlineEventID string `json:"online_event_id"`
	}
	c.ShouldBindBodyWith(&params, binding.JSON)
	err := service.OnlineEvent{}.Draw(c.Request.Context(), params.OnlineEventID)
	response.JSON(c, nil, err)
}

func (OnlineEvent) SetTop(c *gin.Context) {
	var params struct {
		Id string `json:"id"`
	}
	err := c.ShouldBindBodyWith(&params, binding.JSON)
	if err != nil {
		response.JSON(c, nil, err)
		return
	}

	db := mysql.NewDB()
	err = service.OnlineEvent{}.SetTop(c.Request.Context(), db, params.Id)
	response.JSON(c, nil, err)
}

func (OnlineEvent) CancelTop(c *gin.Context) {
	var params struct {
		Id string `json:"id"`
	}
	err := c.ShouldBindBodyWith(&params, binding.JSON)
	if err != nil {
		response.JSON(c, nil, err)
		return
	}

	db := mysql.NewDB()
	err = service.OnlineEvent{}.CancelTop(c.Request.Context(), db, params.Id)
	response.JSON(c, nil, err)
}

func (OnlineEvent) SetSort(c *gin.Context) {
	var params struct {
		Id   string `json:"id"`
		Sort int    `json:"sort"`
	}
	err := c.ShouldBindBodyWith(&params, binding.JSON)
	if err != nil {
		response.JSON(c, nil, err)
		return
	}

	db := mysql.NewDB()
	err = service.OnlineEvent{}.SetSort(c.Request.Context(), db, params.Id, params.Sort)
	response.JSON(c, nil, err)
}

func (OnlineEvent) SetVisible(c *gin.Context) {
	var params struct {
		Id      string `json:"id"`
		Visible int    `json:"visible"`
	}
	err := c.ShouldBindBodyWith(&params, binding.JSON)
	if err != nil {
		response.JSON(c, nil, err)
		return
	}

	err = service.OnlineEvent{}.SetVisible(c.Request.Context(), params.Id, params.Visible)
	if err != nil {
		response.JSON(c, nil, err)
		return
	}

	response.JSON(c, nil, nil)
}
